﻿using Abp.Domain.Repositories;
using Abp.Extensions;
using Abp.Threading;
using Mt.Site.Core.ContentManagement.Entities;
using Mt.Site.Core.DiyContent.Form.Entities;
using Mt.Site.Core.Navigations.Enums;
using Mt.Site.Core.Storage;
using Mt.Site.Core.VersionBackup.Entities;
using Mt.Site.Core.WorkFlows.Process;
using Mt.Site.Core.WorkFlows.Process.Entities;
using Mt.Site.Core.WorkFlows.Process.Models;
using Mt.Site.Core.WorkFlows.Process.Stores;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace Mt.Site.Core.WorkFlows.Diy.Plugin.Impl.tougao
{
    public class TougaoPlugin : WorkFlowPluginFunctionsBase
    {
        public const string Name = "WF.tougao";

        public override string DisplayName => "新闻投稿";

        public override string UniqeName => Name;

        private readonly IRepository<Content2, Guid> _contentRepository;
        private readonly IRepository<ContentField, long> _contentFieldRepository;
        private readonly IRepository<ContentBody, long> _contentBodyRepository;
        private readonly IRepository<BackupBody, long> _backupBodyRepository;
        private readonly IRepository<FileObject,Guid> _fileObjectRepository;
        private readonly IRepository<ContentMenu, Guid> _contentMenuRepository;

        private readonly IWorkFlowFormDataStore _workFlowFormDataStore;

        public TougaoPlugin(
            IRepository<Content2, Guid> contentRepository,
            IRepository<ContentField, long> contentFieldRepository,
            IRepository<ContentBody, long> contentBodyRepository,
            IRepository<BackupBody, long> backupBodyRepository,
            IRepository<FileObject, Guid> fileObjectRepository,
            IRepository<ContentMenu, Guid> contentMenuRepository,
            IWorkFlowFormDataStore workFlowFormDataStore)
        {
            _contentRepository = contentRepository;
            _contentFieldRepository = contentFieldRepository;
            _contentBodyRepository = contentBodyRepository;
            _backupBodyRepository = backupBodyRepository;
            _fileObjectRepository = fileObjectRepository;
            _contentMenuRepository = contentMenuRepository;
            _workFlowFormDataStore = workFlowFormDataStore;
        }

        public override async Task AfterFinishedAsync(IWorkFlowManager workFlowManager)
        {
            var paperId = workFlowManager.PaperId;
            var data = await _workFlowFormDataStore.GetAllFieldAsync(paperId);

            var menuIds = data[WorkFlowConst.FieldName.Content2.Menu.ToPascalCase()];
            var menuIdList = menuIds.GetArryFromStrBySplit<long>(WorkFlowConst.SplitChars);
            if (menuIdList.Length > 0)
            {
                var entity = new Content2();
                entity.Id = Guid.NewGuid();
                entity.Title = data[WorkFlowConst.FieldName.Content2.Title.ToPascalCase()];
                entity.PublishTime = long.Parse(data[WorkFlowConst.FieldName.Content2.PublishTime.ToPascalCase()]);
                entity.Str1 = data[WorkFlowConst.FieldName.Content2.Beizhu.ToPascalCase()];
                entity.Str10 = data[WorkFlowConst.FieldName.Content2.Source.ToPascalCase()];
                entity.Order = 10000;
                entity.MenuId = menuIdList[0];
                entity.IsActive = true;

                // 如果有更多的字段，这里需要转移过去 backupBody，workFlowFormData表 转到  contentBody  contentField
                var body = await _backupBodyRepository.FirstOrDefaultAsync(t=>t.ContentId == paperId);
                if(body != null)
                {
                    entity.Body = body?.Value;
                    await _backupBodyRepository.DeleteAsync(body); 
                }

                await _contentRepository.InsertAsync(entity);
                // menu
                foreach (var menuId in menuIdList)
                {
                    await _contentMenuRepository.InsertAsync(new ContentMenu
                    {
                        MenuId = menuId,
                        ContentId = entity.Id,
                        EntityTypeName = entity.GetType().Name,
                        ManagementType = ManagementType.Manage,
                        Order = 10000,
                        PublishTime = entity.PublishTime
                    });
                }

                //附件
                var allfiles = await _fileObjectRepository.GetAllListAsync(t => t.ContentId == paperId);
                foreach (var item in allfiles)
                {
                    item.ContentId = entity.Id;
                }

                await _workFlowFormDataStore.UpdateOrInsertSpecialFieldAsync(
                    WorkFlowConst.FieldName.Content2.ContentId.ToPascalCase(), paperId, entity.Id.ToString());
            }
        }


        public override async Task BeforeResumeExecuteAsync(IWorkFlowSuperManager workFlowManager, Guid paperId)
        {
            //删除已录入的稿件
            var contentIdStr = await _workFlowFormDataStore.GetSpecialFieldAsync(
                WorkFlowConst.FieldName.Content2.ContentId.ToPascalCase(), paperId);
            if (!contentIdStr.IsNullOrEmpty())
            {
                var contentId = Guid.Parse(contentIdStr);
                var content = await _contentRepository.GetAsync(contentId);

                var body = new BackupBody { ContentId = paperId, FieldName = "Body", Value = content.Body };
                await _backupBodyRepository.InsertAsync(body);

                await _contentRepository.DeleteAsync(content);

                await _contentFieldRepository.DeleteAsync(t => t.ContentId == contentId);
 
                await _contentMenuRepository.DeleteAsync(t => t.ContentId == contentId);
                //附件
                var allfiles = await _fileObjectRepository.GetAllListAsync(t => t.ContentId == contentId);
                foreach (var item in allfiles)
                {
                    item.ContentId = paperId;
                }

                var allBody = await _contentBodyRepository.GetAllListAsync(t => t.ContentId == contentId);
                foreach (var item in allBody)
                {
                    var body2 = new BackupBody { ContentId = paperId, FieldName = item.FieldName, Value = item.Value };
                    await _backupBodyRepository.InsertAsync(body2);
                }
                await _contentBodyRepository.DeleteAsync(t => t.ContentId == contentId);
            }
        }

        public override bool CleanMsgWhenDrawback(IWorkFlowManager workFlowManager)
        {
            return true;
        }

        public override Task AfterSuperSaveFormAsync(UpdateFormDataInput input, WorkFlowPaper paper, IWorkFlowSuperManager workFlowManager)
        {
            if (input.Values.ContainsKey(WorkFlowConst.FieldName.Content2.Title))
            {
                paper.ChangeTitle(input.Values[WorkFlowConst.FieldName.Content2.Title]);
            }

            if (input.Values.ContainsKey(WorkFlowConst.FieldName.Content2.PublishTime))
            {
                paper.ChangeRegistrationTime(input.Values[WorkFlowConst.FieldName.Content2.PublishTime]);
            }
            else
            {
                //当前时间
                paper.ChangeRegistrationTime(null);
            }

            return AbpTaskCache.CompletedTask;
        }

        public override async Task AfterGetDataForReadOnlyAsync(GetFormDataOutput output)
        {
            output.OtherData = new Dictionary<string, object>();

            // 如果数据已复制到内容表
            if (output.Data.ContainsKey(WorkFlowConst.FieldName.Content2.ContentId)
                && Guid.TryParse(output.Data[WorkFlowConst.FieldName.Content2.ContentId] as string, out Guid contentId))
            {
                var content = await _contentRepository.FirstOrDefaultAsync(c => c.Id == contentId);
                if(content != null)
                {
                    output.OtherData.Add("body", content.Body);
                }

                var datas = await _contentBodyRepository.GetAllListAsync(c => c.ContentId == contentId);
                foreach (var c in datas)
                {
                    output.OtherData.Add(c.FieldName.ToCamelCase(), c.Value as object);
                }
            }
        }
    }
}
